// KnowledgeNode.js - 知识树节点数据模型
const mongoose = require('mongoose');

// 知识树节点模式
const knowledgeNodeSchema = new mongoose.Schema({
  // 节点标题
  title: {
    type: String,
    required: [true, '节点标题不能为空'],
    trim: true
  },
  
  // 节点内容
  content: {
    type: String,
    trim: true,
    default: ''
  },
  
  // 父节点ID
  parentId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'KnowledgeNode',
    default: null  // null表示根节点
  },
  
  // 同级节点排序
  order: {
    type: Number, 
    default: 0
  },
  
  // 节点层级 (可选，可以通过parentId计算)
  level: {
    type: Number,
    default: 0
  },
  
  // 创建者 暂时没啥用 没想过鉴权
  // createdBy: {
  //   type: mongoose.Schema.Types.ObjectId,
  //   ref: 'User'
  // }
}, { 
  // 添加时间戳字段
  timestamps: true,
  // 配置JSON序列化
  toJSON: {
    virtuals: true,
    transform: function(doc, ret) {
      delete ret._id; // 因为开了virtuals这个虚拟属性后，他会默认给出一个id，不需要_id了
      delete ret.__v;
      return ret;
    }
  },
  toObject: { virtuals: true }
});

// 虚拟字段 - 子节点
knowledgeNodeSchema.virtual('children', {
  ref: 'KnowledgeNode',
  localField: '_id',
  foreignField: 'parentId',
  options: { sort: { order: 1 } } // 按order字段排序
});

// 静态方法 - 获取整棵树
/*
这段代码的作用是：因为mongoose中存储的数据并不是树形格式，在这里转化为树形格式
1.找出所有根节点（parentId: null）
2.按 order 排序 order: 1：表示按照 order 字段升序排列。数字 1 表示升序，而 -1 则表示降序
3.通过 .populate('children') 自动填充每个节点的子节点
4.并且这个 populate 是递归的，最多支持？ 层嵌套
5.最终返回一个具有嵌套结构的树形数组
*/
knowledgeNodeSchema.statics.getTree = async function() {
  // 获取所有根节点
  const roots = await this.find({ parentId: null })
    .sort({ order: 1 })
    .populate({
      path: 'children',          // 第1层子节点
      populate: {
        path: 'children',        // 第2层子节点
        populate: {
          path: 'children',      // 第3层子节点
          populate: {
            path: 'children',    // 第4层子节点
            populate: {
              path: 'children',  // 第5层子节点
              populate: 'children' // 第6层子节点
            }
          }
        }
      }
    });
  
  return roots;
};

// 静态方法 - 获取某节点及其所有子节点5级
knowledgeNodeSchema.statics.getNodeWithChildren = async function(nodeId) {
  const node = await this.findById(nodeId)
    .populate({
      path: 'children',          // 第1层子节点
      populate: {
        path: 'children',        // 第2层子节点
        populate: {
          path: 'children',      // 第3层子节点
          populate: {
            path: 'children',    // 第4层子节点
            populate: 'children' // 第5层子节点
          }
        }
      }
    });
  
  return node;
};

// 实例方法 - 更新子节点的level
knowledgeNodeSchema.methods.updateChildrenLevel = async function() {
  const newLevel = this.level + 1;
  const children = await mongoose.model('KnowledgeNode').find({ parentId: this._id });
  
  for (const child of children) {
    child.level = newLevel;
    await child.save();
    await child.updateChildrenLevel(); // 递归更新子节点
  }
};

// 创建模型
const KnowledgeNode = mongoose.model('KnowledgeNode', knowledgeNodeSchema);

module.exports = KnowledgeNode; 